package com.tyl.xtk.config;

import com.tyl.xtk.beans.pojo.FieldError;
import com.tyl.xtk.beans.vo.Result;
import com.tyl.xtk.exception.ServiceException;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 1. 处理 @RequestBody 上 @Valid/@Validated 失败
     **/
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> handleBind(MethodArgumentNotValidException ex) {
        List<FieldError> list = ex.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(fieldError -> {
                    FieldError error = new FieldError();
                    error.setField(fieldError.getField());
                    error.setMessage(fieldError.getDefaultMessage());
                    error.setRejectedValue(fieldError.getRejectedValue());
                    return error;
                }).toList();
        return Result.fail(400, "参数校验失败", list);
    }

    /**
     * 2. 处理 @PathVariable / @RequestParam 上 @Validated 失败
     **/
    @ExceptionHandler(ConstraintViolationException.class)
    public Result<?> handleConstraint(ConstraintViolationException ex) {
        List<String> list = ex.getConstraintViolations()
                .stream()
                .map(ConstraintViolation::getMessage)
                .toList();
        return Result.fail(400, "参数校验失败", list);
    }

    /**
     * 处理业务异常
     */
    @ExceptionHandler(ServiceException.class)
    public Result<?> handleServiceException(ServiceException ex) {
        log.error(ex.getMessage(), ex.getCause());
        return Result.fail(ex.getCode(), ex.getMessage(), "");
    }

    /**
     * 处理其他异常
     */
    @ExceptionHandler(Exception.class)
    public Result<?> handleException(Exception ex) {
        log.error(ex.getMessage(), ex.getCause());
        return Result.fail(400, ex.getMessage(), "");
    }


}